package org.yu.register.entity;

import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.EntityDamageSource;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.projectile.ThrowableProjectile;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.yu.register.EntityRegister;
import org.yu.register.MobEffectRegister;

import javax.annotation.Nonnull;

public class JudgementOfShamashEntity extends ThrowableProjectile{
    private final AABB aabb=new AABB(-5,-5,-5,5,5,5);
    protected boolean canDestroyBlock=false;
    private int aliveTimes=200;
    {
        this.noCulling = true;
        this.invulnerableTime=Integer.MAX_VALUE;

    }
    private final DamageSource fireMagicDamage;
    public JudgementOfShamashEntity(EntityType<JudgementOfShamashEntity> entityType, Level level) {
        super(entityType, level);
        fireMagicDamage=DamageSource.IN_FIRE.setMagic().bypassMagic();
    }

    public JudgementOfShamashEntity(LivingEntity livingEntity, Level level) {
        super(EntityRegister.judgementOfShamash.get(), livingEntity, level);
        fireMagicDamage=new EntityDamageSource("mob",livingEntity).setMagic().setIsFire().bypassMagic();
    }


    private ParticleOptions getParticle() {
       return ParticleTypes.FLAME;
    }

    @Override
    public void handleEntityEvent(byte pId) {
            ParticleOptions particleoptions = this.getParticle();
            for(int i = 0; i < 8; ++i) {
                this.level.addParticle(particleoptions, this.getX(), this.getY(), this.getZ(), 0.0D, 0.0D, 0.0D);
            }
    }


    @Override
    protected void defineSynchedData() {

    }

    @Override
    public void tick() {
        super.tick();
        var realX=Math.sin(getXRot())+getX();
        var realY=Math.sin(getYRot())+getY();
        var realZ=Math.cos(getXRot())+getZ();
        if(level.isClientSide) {
            for (int x = -20; x < 20; x++) {
                level.addParticle(ParticleTypes.FLAME, true, realX + x / 4f, realY, realZ, 0, 0, 0);
            }
            for (int y = -16; y < 0; y++) {
                level.addParticle(ParticleTypes.FLAME, true, realX, realY + y / 4f, realZ, 0, 0, 0);
            }
            for (int z = -20; z < 20; z++) {
                level.addParticle(ParticleTypes.FLAME, true, getX(), getY(), getZ() + z / 2f, 0, 0, 0);
            }
        }
        event(new Vec3(realX,realY,realZ));
    }
    protected synchronized void event(Vec3 xyz){
        if(level instanceof ServerLevel serverLevel){
            if(aliveTimes>0)aliveTimes--;
            else this.discard();
            var ab=aabb.move(getX(),getY(),getZ());
            serverLevel.getEntities(this,aabb.move(xyz),this::canHitEntity).
                    forEach(entity -> {
                        entity.hurt(fireMagicDamage, 5);
                        entity.setSecondsOnFire(1);
                        if(entity instanceof LivingEntity livingEntity){
                            var effect=livingEntity.getEffect(MobEffectRegister.vulnerability.get());
                            if(effect==null||effect.getDuration()<5)
                            livingEntity.addEffect(new MobEffectInstance(MobEffectRegister.vulnerability.get(),60));
                        }
                    });
            if(canDestroyBlock) {
                int x0 = (int) ab.minX;
                int x1 = (int) ab.maxX;
                int y0 = (int) ab.minY;
                int y1 = (int) ab.maxY;
                int z0 = (int) ab.minZ;
                int z1 = (int) ab.maxZ;
                for (int x = x0; x < x1; x++) {
                    for (int y = y0; y < y1; y++) {
                        for (int z = z0; z < z1; z++) {
                            var pos = new BlockPos(x, y, z);
                            if (!level.getBlockState(pos).isAir()) {
                                serverLevel.destroyBlock(pos, false);
                            }
                        }
                    }
                }
            }
            }
        }

    @Override
    protected void onInsideBlock(BlockState pState) {
        super.onInsideBlock(pState);
    }

    @Override
    public void remove(RemovalReason pReason) {
        super.remove(pReason);
    }

    @Override
    protected boolean canHitEntity(@Nonnull Entity entity) {
        return getOwner()!=entity&& !(entity instanceof ItemEntity);
    }

    @Override
    protected float getGravity() {
        return 0;
    }

    @Override
    public boolean shouldRender(double pX, double pY, double pZ) {
        return super.shouldRender(pX, pY, pZ);
    }
}
